package edu.snake.implement.model.character.listenerDecorator;


import edu.snake.core.model.character.Character;
import edu.snake.core.model.character.CharacterState;
import edu.snake.core.model.character.Course;
import edu.snake.core.model.character.Movement;
import edu.snake.core.utils.Listeners;
import edu.snake.implement.model.CharacterName;
import edu.snake.implement.model.arena.Direction;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;
import java.util.Iterator;

public class CharacterListenerAdapterBaseImpl implements Character, Listeners {
    protected final Character character;
    private final Listeners listeners;


    public CharacterListenerAdapterBaseImpl(Character character) {
        this.character = character;
        this.listeners = new ListenersImpl();
    }

    @Override
    public CharacterName getName() {
        return character.getName();
    }

    @Override
    public Character getChild(int i) {
        return character.getChild(i);
    }

    @Override
    public Character move() {
        return character.move();
    }

    @Override
    public void remove(Character character) {
        this.character.remove(character);
    }

    @Override
    public int size() {
        return character.size();
    }

    @Override
    public void add(Character character) {
        this.character.add(character);
    }

    @Override
    public boolean isAlive() {
        return character.isAlive();
    }

    @Override
    public void setAlive(boolean alive) {
        character.setAlive(alive);
    }

    @Override
    public Direction getDirection() {
        return character.getDirection();
    }

    @Override
    public void setDirection(Direction direction) {
        character.setDirection(direction);
    }

    @Override
    public Iterator<Character> iterator() {
        return character.iterator();
    }

    @Override
    public CharacterState getState() {
        return character.getState();
    }

    @Override
    public void setState(CharacterState characterState) {
        character.setState(characterState);
    }

    @Override
    public void setMovement(Movement movement) {
        character.setMovement(movement);
    }

    @Override
    public int getId() {
        return character.getId();
    }

    @Override
    public void setCourse(Course course) {
        character.setCourse(course);
    }

    @Override
    public boolean equals(Object o) {
        return character.equals(o);
    }

    @Override
    public int hashCode() {
        return character.hashCode();
    }

    @Override
    public String toString() {
        return character.toString();
    }


    //region Listeners
    @Override
    public void addActionListener(ActionListener listener) {
        listeners.addActionListener(listener);
    }

    @Override
    public ActionListener[] getActionListeners() {
        return listeners.getActionListeners();
    }

    @Override
    public String getActionCommand() {
        return listeners.getActionCommand();
    }

    @Override
    public void removeActionListener(ActionListener listener) {
        listeners.removeActionListener(listener);
    }

    @Override
    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
        return listeners.getListeners(listenerType);
    }

    @Override
    public Object[] getListenerList() {
        return listeners.getListenerList();
    }

    protected void fireActionPerformed(ActionEvent e) {
        // Guaranteed to return a non-null array
        Object[] listeners = this.listeners.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            if (listeners[i] == ActionListener.class) {
                ((ActionListener) listeners[i + 1]).actionPerformed(e);
            }
        }
    }
    //endregion
}
